package com.tanhua.manage.aop;

import cn.hutool.core.date.DateTime;
import cn.hutool.http.server.HttpServerRequest;
import cn.hutool.json.JSONObjectIter;
import com.alibaba.fastjson.JSON;
import com.tanhua.domain.db.User;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.domain.AdminLog;
import com.tanhua.manage.domain.OperLog;
import com.tanhua.manage.interceptor.AdminHolder;



import com.tanhua.manage.service.AdminService;
import com.tanhua.manage.service.IAdminLogService;
import com.tanhua.manage.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.sql.Date;
import java.time.LocalDateTime;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * 管理员记录日志操作
 * @Author LianQingSen
 */
@Aspect
@Component
@Slf4j
public class AdminLogAspect {


    @Pointcut("execution(public * com.tanhua.manage.controller.*.*(..))")
    public void logAspect() {
    }

    @Autowired
    private IAdminLogService iAdminLogService;

    @Around("logAspect()")
    public Object adminAround(ProceedingJoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        long startDate = System.currentTimeMillis();

        Object proceed = null;
        try {
            //判断执行的是否为方法
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();
            OperLog operLog = method.getAnnotation(OperLog.class);
            Object[] args = joinPoint.getArgs();

            String clazzName = joinPoint.getTarget().getClass().getName();
            proceed = joinPoint.proceed(args);
            AdminLog adminLog = new AdminLog();
            if (operLog != null) {
                if ("POST".equalsIgnoreCase(request.getMethod())){
                    Object arg = args[0];
                    adminLog.setOperParameter(JSON.toJSONString(arg));
                }
                adminLog.setCreated(LocalDateTime.now());
                adminLog.setAddressIp(getRequestIP(request));
                adminLog.setOperUrl(request.getServletPath());
                adminLog.setOperModul(operLog.operModul());
                adminLog.setOperType(operLog.operType());
                adminLog.setTimeConsuming(System.currentTimeMillis() - startDate);
                adminLog.setOperMethodName(clazzName + "." + method.getName());
                Admin admin = AdminHolder.get();
                if (StringUtils.isEmpty(admin)) {
                    if ("/system/users/login".equalsIgnoreCase(request.getServletPath())) {
                        Map<String, Object> arg = (Map<String, Object>) args[0];
                        String username = (String) arg.get("username");
                        //TODO 这里的id可以从数据库中获取
                        adminLog.setOperUserName(username);
                        System.out.println(adminLog);
                        iAdminLogService.saveLog(adminLog);
                        return proceed;
                    }
                }
                adminLog.setOperUserName(admin.getUsername());
                adminLog.setOperUserId(admin.getId());
                System.out.println(adminLog);
                iAdminLogService.saveLog(adminLog);
                return proceed;
            }

        } catch (Throwable throwable) {
            throwable.printStackTrace();
            log.info("throwable {}", throwable);

        }
        return proceed;
    }

    /**
     * 获取当前请求的IP,对使用代理后都有效
     *
     * @return
     */
    public static String getRequestIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}
